<?php
/**
 * Copyright (c) 2006-2007, Julien PORTALIER
 * 
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 * 
 * To use you'll need to:
 * 
 *    1. download SwiftMailer 3.2.x from http://swiftmailer.org
 *    2. unpack it in somewhere
 *    3. rename the lib/ folder to swift/
 *    4. move it to the vendors/ directory
 * 
 * @copyright    Copyright (c) 2006-2007, Julien PORTALIER
 * @link         http://feather-cm.googlecode.com/
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class SwiftComponent
{
	protected $controller;
	protected $recipients;
	protected $from;
	public    $mailer;
	public    $error;
	
	function startup(Controller &$controller)
	{
		$this->controller = &$controller;
	}
	
	// swiftmailer
	
	function connect()
	{
		// loads required libs
		Load::vendors(
			'swift'.DS.'Swift.php',
			'swift'.DS.'Swift'.DS.'Connection'.DS.Core::swift_protocol.'.php'
		);
		
		// creates transport method
		switch(Core::swift_protocol)
		{
			case 'SMTP':
				$conn = new Swift_Connection_SMTP(Core::swift_options);
				
				// SMTP auth?
				if (Core::smtp_username)
				{
					$conn->setUsername(Core::smtp_username);
					$conn->setPassword(Core::smtp_password);
				}
				break;
			
			case 'Sendmail':
				$conn = new Swift_Connection_Sendmail(Core::swift_options);
				break;
			
			case 'NativeMail':
				$conn = new Swift_Connection_NativeMail(Core::swift_options);
				break;
			
			default:
				trigger_error('You must set a known protocol (SMTP, Sendmail, NativeMail) for use with swift.', E_USER_ERROR);
		}
		
		// creates mailer
		$this->mailer = new Swift($conn);
		
		// creates a recipient list
		$this->recipients = new Swift_RecipientList();
	}
	
	function send($subject='', $from=null, $html_body=null, $method='send')
	{
		if (!isset($this->mailer))
			$this->connect();
		
		# from who?
		if (isset($from))
		{
			if (is_array($from))
			{
				# email + name
				list($email, $name) = $from;
				$this->setFrom($email, $name);
			}
			else
			{
				# email
				$this->from = $from;
			}
		}
		
		# multipart body
		$message = new Swift_Message($subject);
#		$message->setEncoding('quoted-printable');
		$message->setCharset(Core::charset);
		
		# text/html part
#		if (is_null($html_body))
#			$html_body = $this->renderBody();
		
#		if (DEBUG)
#			print_r($html_body);
		
		# h4ck to deal with hotmail.com
#		if (!$this->hasHotmailRecipient())
#			$charset = Core::charset;
#		else
#		{
#			$charset   = Core::email_charset;
#			$html_body = htmlentities(html_entity_decode($html_body), ENT_NOQUOTES, Core::charset);
#			$html_body = str_replace(array('&lt;', '&gt;'), array('<', '>'), $html_body);
#			$html_body = preg_replace('/&amp;#(\d+);/', '&#\1;', $html_body);
#		}
		
		# text/html part
		if (is_null($html_body)) {
			$html_body = $this->renderBody();
		}
		$part_html = new Swift_Message_Part($html_body, 'text/html', '8bit', Core::charset);
		$message->attach($part_html);
		
		# text/plain part
		$tmp = APP.'tmp'.DS.'email.'.md5($html_body);
		file_put_contents($tmp, $html_body);
		$cmd = str_replace(
			array(':file', ':charset', ':locale'),
			array($tmp,    Core::charset,   $this->controller->Locale->get().'.'.Core::charset),
			Core::email_txt_cmd
		);
		ob_start();
		passthru($cmd, &$rs);
		$plain_body = ob_get_clean();
		unlink($tmp);
		
		if (0 === $rs)
		{
			$part_plain = new Swift_Message_Part($plain_body, 'text/plain', '8bit', Core::charset);
			$message->attach($part_plain);
		}
		
		if (DEBUG)
		{
			#var_dump($message->getEncoding());
			#var_dump($message->getCharset());
			debug($html_body);
			debug($plain_body);
			#debug($message);
			die();
		}
		
		# send
		$nb_recipients = count($this->recipients->getTo()) + count($this->recipients->getCc()) + count($this->recipients->getBcc());
		$nb_sent = $this->mailer->$method($message, $this->recipients, $this->from);
		
		# errors?
		if (!$nb_sent)
			$this->error = _("An error occured and your email wasn't sent.");
		elseif ($nb_sent != $nb_recipients)
			$this->error = _("An error occured and your email wasn't sent to all recipients.");
	}
	
	function batchSend($subject='', $from=null, $html_body=null)
	{
		$this->send($subject, $from, $html_body, 'batchSend');
	}
	
	function setFrom($email, $name=null)
	{
		$this->from = new Swift_Address($email, $name);
	}
	
	function addRecipient($email, $name=null, $method="To")
	{
		if (!isset($this->recipients))
			$this->connect();
		
		$method = "add$method";
		$this->recipients->$method($email, $name);
	}
	
	// internals
	/*
	protected function hasHotmailRecipient()
	{
		$recipients = array_keys(array_merge(
			$this->recipients->getTo(),
			$this->recipients->getCc(),
			$this->recipients->getBcc()
		));
		foreach($recipients as $email)
		{
			if (stripos($email, 'hotmail.com'))
				return true;
		}
		return false;
	}
	*/
	protected function renderBody()
	{
		$autoRender      = $this->controller->autoRender;
		$alreadyRendered = $this->controller->alreadyRendered;
		
		ob_start();
		$this->controller->render('emails'.DS.$this->controller->action, 'email');
		$body = ob_get_clean();
		
		$this->controller->autoRender      = $autoRender;
		$this->controller->alreadyRendered = $alreadyRendered;
		
		return $body;
	}
}
?>